#include "TreeModel.h"
#include <QDebug>

TreeModel::TreeModel(QObject* parent)
    : QAbstractItemModel(parent), m_rootNode(new TreeNode("", "", "Root")) {
}

void TreeModel::expandAll() {
    if (!m_rootNode) return;

    // 递归展开所有节点
    QModelIndex rootIndex = createIndex(0, 0, m_rootNode);

    // 递归展开子节点
    expandChildren(rootIndex);
}

void TreeModel::filter(const QString &text)
{
    beginResetModel();
    m_filterText = text;
    endResetModel();

    expandAll();
}

void TreeModel::expandChildren(const QModelIndex& parent) {  
    int rowCount = this->rowCount(parent);
    for (int i = 0; i < rowCount; ++i) {
        QModelIndex childIndex = index(i, 0, parent);
        if (!childIndex.isValid()) {
            continue;
        }
        
        emit expandTree(childIndex);
        expandChildren(childIndex);
    }
}

TreeModel::~TreeModel() {
    delete m_rootNode;
}

QModelIndex TreeModel::index(int row, int column, const QModelIndex& parent) const {
    if (!hasIndex(row, column, parent))
        return QModelIndex();

    TreeNode* parentNode = getNode(parent);
    int currentRow = 0;
    // 遍历所有子节点
    foreach (TreeNode* child, parentNode->getChildren()) {
        // 检查过滤条件
        if (!filterAcceptsNode(child)) {
            continue;
        }
        
        if (currentRow == row) {
            return createIndex(row, column, child);
        }
        ++currentRow;
    }

    return QModelIndex();
}

QModelIndex TreeModel::parent(const QModelIndex& child) const {
    if (!child.isValid())
        return QModelIndex();

    TreeNode* childNode = getNode(child);
    TreeNode* parentNode = m_nodeMap.value(childNode->getParentId(), m_rootNode);

    if (parentNode == m_rootNode)
        return QModelIndex();

    // 计算父节点在祖父节点中的行号
    TreeNode* grandParent = parentNode->getParent();
    if (!grandParent) {
        return QModelIndex();
    }

    int row = 0;
    foreach (TreeNode* sibling, grandParent->getChildren()) {
        if (sibling == parentNode) {
            return createIndex(row, 0, parentNode);
        }
        if (filterAcceptsNode(sibling)) {
            ++row;
        }
    }

    return QModelIndex();
}

int TreeModel::rowCount(const QModelIndex& parent) const {
    TreeNode* parentNode = getNode(parent);
    int count = 0;
    foreach (TreeNode* child, parentNode->getChildren()) {
        if (filterAcceptsNode(child)) {
            ++count;
        }
    }
    return count;
}

int TreeModel::columnCount(const QModelIndex& parent) const {
    Q_UNUSED(parent)
    return 1;
}

QVariant TreeModel::data(const QModelIndex& index, int role) const {
    if (!index.isValid()) {
        if (role == Qt::CheckStateRole) {
            return Qt::Unchecked;
        }
        return QVariant();
    }

    TreeNode* node = getNode(index);
    if (role == Qt::DisplayRole) {
        return QVariant::fromValue(node->getId() + "-" + node->getName());
    } else if (role == Qt::CheckStateRole) {
        return node->getCheckState();
    }

    return QVariant();
}

bool TreeModel::setData(const QModelIndex& index, const QVariant& value, int role) {
    if (!index.isValid() || role != Qt::CheckStateRole)
        return false;

    TreeNode* node = getNode(index);
    int checkState = value.toInt();

    node->setCheckState(checkState);

    // 更新所有子节点状态
    if (!node->getChildren().isEmpty()) {
        updateChildrenCheckedState(node, checkState);
    }
    
    // 更新父节点的勾选状态
    updateParentCheckedState(node, checkState);

//    emit dataChanged(index, index);

    updateAllNodes();

    return true;
}

Qt::ItemFlags TreeModel::flags(const QModelIndex& index) const {
    if (!index.isValid())
        return Qt::NoItemFlags;

    return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable;
}

//注意服务端传过来的一级组织机构的父节点是空的，我要给设置成一级组织机构的父节点是-1
void TreeModel::setTreeData(const QVector<TreeNode>& nodes) {
    beginResetModel();

    // Clear existing data
    delete m_rootNode;
    m_rootNode = new TreeNode("-1", "", "Root");
    m_nodeMap.clear();

    // Build tree structure
    QHash<QString, TreeNode*> tempMap;
    foreach (const TreeNode& node, nodes) {
        TreeNode* newNode = new TreeNode(node);
        tempMap.insert(newNode->getId(), newNode);
    }

    // Build parent-child relationships
    QList<TreeNode*> sortedNodes = tempMap.values();
    // 按ID升序排序
    std::sort(sortedNodes.begin(), sortedNodes.end(), [](TreeNode* a, TreeNode* b) {
        return a->getId() < b->getId();
    });

    foreach (TreeNode* node, sortedNodes) {
        TreeNode* parent = tempMap.value(node->getParentId(), m_rootNode);
        node->setRow(parent->getChildren().count());
        node->setParent(parent);
        parent->addChild(node);
        m_nodeMap.insert(node->getId(), node);

        if("-1" == node->getParentId()){
            m_FirstTreeId = node->getId();
        }
    }

    TreeNode* firstTree = tempMap.value(m_FirstTreeId, m_rootNode);
    // 初始化节点路径哈希表
    updateGroupNameHash(firstTree);

    endResetModel();
}

QVector<QString> TreeModel::getCheckedNodes() const {
    QVector<QString> checkedIds;
    foreach (TreeNode* node, m_nodeMap) {
        if (Qt::Checked == node->getCheckState()) {
            checkedIds.append(node->getId());
        }
    }
    return checkedIds;
}

void TreeModel::setCheckedById(const QVector<QString>& ids, int checked) {
    if(ids.isEmpty())
        return;

    for(const auto& id : ids){
        TreeNode* node = m_nodeMap.value(id, m_rootNode);
        if (node) {
            QModelIndex index = createIndex(node->getRow(), 0, node);
            setData(index, checked, Qt::CheckStateRole);
        }
    }

    expandAll();
}

TreeNode* TreeModel::getNode(const QModelIndex& index) const {
    if (index.isValid()) {
        return static_cast<TreeNode*>(index.internalPointer());
    }
    return m_rootNode;
}

bool TreeModel::filterAcceptsNode(TreeNode *node) const
{
    if (m_filterText.isEmpty()) {
        return true;
    }

    // 检查当前节点是否匹配
    bool nodeMatches = node->getName().contains(m_filterText, Qt::CaseInsensitive);

//    qDebug()<<"hdj---filterAcceptsNode---getName:"<<node->getName()
//           <<", m_filterText:"<<m_filterText <<", nodeMatches:"<<nodeMatches;

    // 检查子节点是否匹配
    bool childMatches = false;
    foreach (TreeNode* child, node->getChildren()) {
        if (filterAcceptsNode(child)) {
            childMatches = true;
            break;
        }
    }

    // 如果当前节点或任何子节点匹配，则显示该节点
    return nodeMatches || childMatches;
}

void TreeModel::updateParentCheckedState(TreeNode* node, int checkstate) {
    if (!node || node == m_rootNode)
        return;

    TreeNode* parent = m_nodeMap.value(node->getParentId(), m_rootNode);
    if (!parent || parent == m_rootNode)
        return;

    // 父节点选中状态只影响子节点，不影响自身
    // 当前节点选中状态，父节点如果是未选中状态，则变为部分选中状态；
    // 当前节点未选中状态且父节点不是选中状态，父节点如果所有的子节点有部分选中状态，则变为部分选中状态、如果都未选中，则变为未选中状态；
    if(Qt::Unchecked == parent->getCheckState() && Qt::Checked == checkstate){
        parent->setCheckState(Qt::PartiallyChecked);
    }
    else if(Qt::Unchecked == checkstate){
        if(Qt::Checked != parent->getCheckState()){
            if(Qt::Unchecked == getAllChildCheckState(parent)){
                parent->setCheckState(Qt::Unchecked);
            }
            else if(Qt::PartiallyChecked == getAllChildCheckState(parent)){
                parent->setCheckState(Qt::PartiallyChecked);
            }
        }
    }

//    QModelIndex parentIndex = createIndex(parent->getRow(), 0, parent);
//    emit dataChanged(parentIndex, parentIndex);

//    qDebug()<<"hdj--999--upparent00--node:"<<node->getName()<<", checkstate:"<<checkstate
//           <<", parentName:"<<parent->getName()<<", parentState:"<<parent->getCheckState()
//          <<"m_m_nodeMap:"<<m_nodeMap;

    // 递归更新父节点的父节点
    updateParentCheckedState(parent, checkstate);
}

int TreeModel::getAllChildCheckState(TreeNode *parent)
{
    if (!parent || parent->getChildren().isEmpty())
        return Qt::Unchecked;

    bool hasChecked = false;
    bool hasUnchecked = false;
    bool hasPartial = false;

    foreach (TreeNode* child, parent->getChildren()) {
        int state = child->getCheckState();
        
        if (state == Qt::Checked) {
            hasChecked = true;
        } else if (state == Qt::Unchecked) {
            hasUnchecked = true;
        } else { // PartiallyChecked
            hasPartial = true;
        }

        // 递归检查子节点的子节点
        if (!child->getChildren().isEmpty()) {
            int childState = getAllChildCheckState(child);
            if (childState == Qt::PartiallyChecked) {
                hasPartial = true;
            } else if (childState == Qt::Checked) {
                hasChecked = true;
            } else {
                hasUnchecked = true;
            }
        }
    }

    if (hasPartial) {
        return Qt::PartiallyChecked;
    }
    else if (hasChecked && hasUnchecked) {
        return Qt::PartiallyChecked;
    }
    else if (hasChecked) {
        return Qt::Checked;
    }
    
    return Qt::Unchecked;
}

void TreeModel::updateGroupNameHash(TreeNode* node, const QString& parentIdPath, const QString& parentNamePath) {
    if (!node)
        return;
    
    // 构建当前节点路径
    QString currentIdPath{QLatin1String("")};
    QString currentNamePath{QLatin1String("")};
    currentIdPath = parentIdPath.isEmpty() ? node->getId() : parentIdPath + "_" + node->getId();
    currentNamePath = parentNamePath.isEmpty() ? node->getName() : parentNamePath + "_" + node->getName();

    m_GroupNameHash[node->getId()] = {currentIdPath, currentNamePath};

    if(m_FirstTreeId == node->getId()){
        currentIdPath = QLatin1String("");
        currentNamePath = QLatin1String("");
    }
    
    // 递归更新子节点路径
    foreach (TreeNode* child, node->getChildren()) {
        updateGroupNameHash(child, currentIdPath, currentNamePath);
    }
}

void TreeModel::updateChildrenCheckedState(TreeNode* node, int checkstate) {
    if (!node)
        return;

    // 递归地设置所有子节点的勾选状态
    foreach (TreeNode* child, node->getChildren()) {

//        qDebug()<<"hdj--up--childName00:"<<child->getName()<<", child->getCheckState():"<<child->getCheckState()
//               <<", parentName:"<<node->getName()<<", checked:"<<checkstate;

        // 如果子节点状态与要设置的状态不同才更新
        if (child->getCheckState() != checkstate) {

            child->setCheckState(checkstate);
//            qDebug()<<"hdj--up--childName11:"<<child->getName()<<", checkstate:"<<checkstate<<", child->getCheckState():"<<child->getCheckState();
//            int childRow = node->getChildren().indexOf(child);
//            QModelIndex childIndex = createIndex(childRow, 0, child);
//            emit dataChanged(childIndex, childIndex);
        }

        // 递归更新子节点的子节点
        if (!child->getChildren().isEmpty()) {
            updateChildrenCheckedState(child, checkstate);
        }
    }
}

void TreeModel::updateAllNodes() {
    if (!m_rootNode) return;
    
    // 递归更新所有节点
    QModelIndex rootIndex = createIndex(0, 0, m_rootNode);
    updateNode(rootIndex);
}

void TreeModel::updateNode(const QModelIndex& index) {
    if (!index.isValid()) return;
    
    // 发出当前节点更新信号
    emit dataChanged(index, index);
    
    // 递归更新子节点
    int rowCount = this->rowCount(index);
    for (int i = 0; i < rowCount; ++i) {
        QModelIndex childIndex = this->index(i, 0, index);
        updateNode(childIndex);
    }
}
